#include<stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include<iostream>
#include<string>
#include<memory>
#define Print(form , ...) printf(form, ##__VA_ARGS__)
void myprintf(int count,...)
{
    va_list vp;
    va_start(vp,count);
    for(int i = 0; i < count;i++)
    {
        int num = va_arg(vp,int);
        printf("%d\n",num);
    }
    va_end(vp);
}
void myprintf2(const char* form,...)
{
    va_list vp;
    va_start(vp,form);
    char* ret;
    vasprintf(&ret,form,vp);
    printf("%s\n",ret);
    free(ret);
    va_end(vp);
}
void myprintf3()
{
    std::cout<<"exit "<<std::endl;
}
//c++版本
template<class T, class ...Args>
void myprintf3(const T& v, Args&& ...args)
{
    std::cout<<v<<std::endl;
    if((sizeof...(args)) > 0)
    {
        myprintf3(std::forward<Args>(args)...);
    }
    else
    {
        myprintf3();
    }
}
// class Factory
// {
// public:
//     static std::shared_ptr<fruit> Create(const std::string& name)
//     {
//         if(name == "苹果")
//         {
//             return std::make_shared<Apple>();//直接返回shared_ptr<Apple>这个对象
//         }
//         else
//         {
//             return std::make_shared<Banana>();//直接返回shared_ptr<banana>这个对象
//         }
//     }
// };
// class Factory
// {
// public:
//     virtual std::shared_ptr<fruit> Create() = 0;
// };
//工厂方法模式,一个产品建一个工厂类
// class BananaFactory: public Factory
// {
// public:
//     std::shared_ptr<fruit> Create()
//     {
//         return std::make_shared<Banana>();//直接返回shared_ptr<banana>这个对象
//     }
// };
// class AppleFactory:public Factory
// {
// public:
//     std::shared_ptr<fruit> Create()
//     {
//         return std::make_shared<Apple>();//直接返回shared_ptr<Apple>这个对象
//     }
// };

    class fruit
    {
    public:
    virtual void name() =0;
    };
    class Apple: public fruit
    {
    public:
        Apple()
        {
            std::cout<<"i am a apple"<<std::endl;
        }
        static Apple* Create()
        {
            return new Apple();
        }
        void name() override
        {
            std::cout<<"苹果"<<std::endl;
        }
    };
    class Banana: public fruit
    {
    public:
        Banana()
        {
            std::cout<<"i am a banana"<<std::endl;
        }
        static Banana* Create()
        {
            return new Banana();
        }
        void name() override
        {
            std::cout<<"香蕉"<<std::endl;
        }
    };
    class Animal
    {
    public:
        virtual void name() =0;    
    };
    class Dog:public Animal
    {
    public:
        virtual void name()
        {
            std::cout<<"小狗"<<std::endl;
        }   
    };
    class Lion:public Animal
    {
    public:
        virtual void name()
        {
            std::cout<<"狮子"<<std::endl;
        }   
    };


    // //抽象工厂模式
    class Factory
    {
    public:
        virtual std::shared_ptr<fruit> CreateFruit(const std::string& name) = 0;
        virtual std::shared_ptr<Animal> CreateAnimal(const std::string& name) = 0;
    };
    class FruitFactory: public Factory
    {
    public:
        std::shared_ptr<Animal> CreateAnimal(const std::string& name) override
        {
            return std::shared_ptr<Animal>();//此处不能make_shared返回
        }
        std::shared_ptr<fruit> CreateFruit(const std::string& name) override
        {
            if(name == "苹果")
            {
                return std::make_shared<Apple>();//直接返回shared_ptr<Apple>这个对象
            }
            else
            {
                return std::make_shared<Banana>();//直接返回shared_ptr<banana>这个对象
            }
        }
    };
    class AnimalFactory: public Factory
    {
    public:
        std::shared_ptr<fruit> CreateFruit(const std::string& name) override
        {
            return std::shared_ptr<fruit>();//此处不能make_shared返回
        }
        std::shared_ptr<Animal> CreateAnimal(const std::string& name) override
        {
            if(name == "小狗")
            {
                return std::make_shared<Dog>();//直接返回shared_ptr<Dog>这个对象
            }
            else
            {
                return std::make_shared<Lion>();//直接返回shared_ptr<Lion>这个对象
            }
        }
    };
    class FactorProducer
    {
    public:
        static std::shared_ptr<Factory> CreateFactor(const std::string& name)
        {
            if(name == "水果")
            {
                return std::make_shared<FruitFactory>();
            }
            else
            {
                return std::make_shared<AnimalFactory>();
            }
        }
    };
int main()
{
    // int a = 0;
    // Print("hello \n");
    // myprintf(3,1,2,3);
    // myprintf2("hello %d,%d,%d",1,2,3);
    // myprintf3("hello ",1,2,3);
    //简单工厂模式
    // std::shared_ptr<fruit> sf =  Factory::Create("苹果");
    // sf->name();
    // sf = Factory::Create("香蕉");
    // sf->name();
    //工厂方法模式
    // std::shared_ptr<Factory> sf(new AppleFactory());
    // std::shared_ptr<fruit> sfruit = sf->Create();//生产一个苹果
    // sfruit->name();
    // sf.reset(new BananaFactory());//变成香蕉工厂
    // sfruit = sf->Create();//生产一个香蕉
    // sfruit->name();

    //抽象工厂模式
    std::shared_ptr<Factory> ff(new FruitFactory());
    std::shared_ptr<fruit> sf = ff->CreateFruit("苹果"); 
    sf->name();
    sf = ff->CreateFruit("香蕉");
    sf->name();
    std::shared_ptr<Factory> ffactory(new AnimalFactory());
    std::shared_ptr<Animal> sf2 = ffactory->CreateAnimal("小狗"); 
    sf2->name();
    sf2 = ffactory->CreateAnimal("狮子");
    sf2->name();
    return 0;
}